package psn.zjk.common.serialize;

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.runtime.RuntimeSchema;

import java.util.HashMap;

/**
 * @USER white
 * @DATETIME 2021/1/7 17:26
 * @SEE https://github.com/protostuff/protostuff
 */
public class ProtostuffDemo {

    private static HashMap<String, RuntimeSchema> schemas = new HashMap<>();
    private String zz;

    public ProtostuffDemo(String zz) {
        this.zz = zz;
    }

    public static void register(Class clazz) {
//        RuntimeSchema.register(clazz);
        String name = clazz.getName();
        if (!schemas.containsKey(name)) {
            RuntimeSchema schema = RuntimeSchema.createFrom(clazz);
//            Schema<Object> schema = RuntimeSchema.getSchema(clazz);
            schemas.put(name, schema);
        }
    }

    public static <T> byte[] pack(T t) {
        byte[] bytes;
        LinkedBuffer buffer = LinkedBuffer.allocate();
        try {
            RuntimeSchema runtimeSchema = schemas.get(t.getClass().getName());
            bytes = ProtostuffIOUtil.toByteArray(t, runtimeSchema, buffer);
        } finally {
            buffer.clear();
        }
        return bytes;
    }

    public static <T> T unpack(byte[]  bytes,Class<T> clazz){
        RuntimeSchema schema = schemas.get(clazz.getName());
        ProtostuffDemo c = (ProtostuffDemo) schema.newMessage();
        //反序列化后合并到新对象
        ProtostuffIOUtil.mergeFrom(bytes,c,schema);
        return (T) c;
    }

    public static void main(String[] args) {
        //https://github.com/protostuff/protostuff
        ProtostuffDemo.register(ProtostuffDemo.class);
        ProtostuffDemo protostuffDemo = new ProtostuffDemo("zzxx");
        //序列化
        long l = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
            byte[] pack = ProtostuffDemo.pack(protostuffDemo);
//            ProtostuffDemo unpack = ProtostuffDemo.unpack(pack, ProtostuffDemo.class);
//            System.out.println(unpack.zz);

        }
        System.out.println(System.currentTimeMillis()-l);
    }
}
